public class ext_OppSplit {
	
	Private Opportunity Oppty;
	List<Opportunity> oppyList = new List<Opportunity>();
	List<OppLineWrapper> oppLineList = new List<OppLineWrapper>();
	List<OpportunityLineItem> selectedWonOpps = new List<OpportunityLineItem>();
	List<OpportunityLineItem> selectedLostOpps = new List<OpportunityLineItem>();
	List<OpportunityLineItem> selectedPendingOpps = new List<OpportunityLineItem>();
	List<OpportunityLineItem> OppLineItemCopyWon = new List<OpportunityLineItem>();
	List<OpportunityLineItem> OppLineItemCopyLost = new List<OpportunityLineItem>();
	List<OpportunityLineItem> OppLineItemCopyPending = new List<OpportunityLineItem>();
	Map<String, List<OpportunityLineItem>> mapOppLineType = new Map<String, List<OpportunityLineItem>>();
	Map<String, Id> recordTypeMap = new Map<String, Id>();
	

    public ext_OppSplit(ApexPages.StandardController controller) {
	 this.Oppty = (Opportunity)controller.getRecord();
    }
	
	//retreive the close date
	public Opportunity getDateValue() {
		Opportunity mydate = [Select CloseDate from Opportunity where id=: Oppty.Id LIMIT 1];
		return myDate;
	}
	
	
	//use this or the stock code
	public List<OppLineWrapper> getOppLineItems() {
				oppLineList = new List<OppLineWrapper>();	
				for(OpportunityLineItem o : [SELECT Id, ServiceDate, Line_Item_Status__c, OpportunityId, PricebookEntry.Name, Discount, Part_Number__c, 
				Description, UnitPrice, Quantity, Total_Amount_Plus_VAT__c, VAT_Value__c,VAT_Code__c,VAT_Rate__c,Commission__c,
				Freight_Rate__c,Duty__c, Margin__c, UOM__c, Delivery_Days__c, Inquiry_Part_No__c, Product_Group__c, 
				Product_Group_Description__c, Product_Group_Master__c, Item_Number__c, NL_Code__c, NL_Code_Description__c 
				 FROM OpportunityLineItem WHERE OpportunityId =: Oppty.id order by Item_Number__c ASC]) {
					oppLineList.add(new OppLineWrapper(o));
				}
			return oppLineList;

	}
	
	
	
	public class OppLineWrapper {
		public OpportunityLineItem opi {get; set;}
		public Boolean selected {get; set;}
		public String status {get; set;}
		public OppLineWrapper(OpportunityLineItem opps) {
			opi = opps;
			//status = opi.line_item_status__c;
		}
	}
	
	public PageReference Next() {
		selectedWonOpps.clear();
		selectedLostOpps.clear();
		selectedPendingOpps.clear();
		
		PageReference opptyPage;
		
		try{
			
			system.debug('size of oppLineList to be processed by Next => ' + oppLineList.size());
			for(OppLineWrapper oppwrapper : oppLineList) {
				//if(oppwrapper.selected == true) {
					system.debug('check status value => ' + oppwrapper.opi.line_item_status__c + ' /id of => ' + oppwrapper.opi.id);
					
					if(oppwrapper.opi.line_item_status__c == 'won')	
						selectedWonOpps.add(oppwrapper.opi);
					if(oppwrapper.opi.line_item_status__c == 'lost')	
						selectedLostOpps.add(oppwrapper.opi);
					if(oppwrapper.opi.line_item_status__c == 'pending')	
						selectedPendingOpps.add(oppwrapper.opi);
							
				//}
			}
			if(selectedWonOpps.size() > 0)		
			mapOppLineType.put('won', selectedWonOpps);//processSelectedApps(selectedWonOpps, 'won');
				
			if(selectedLostOpps.size() > 0)		
			mapOppLineType.put('lost', selectedLostOpps); //processSelectedApps(selectedLostOpps, 'lost');
	
			if(selectedPendingOpps.size() > 0)		
			mapOppLineType.put('pending', selectedPendingOpps); //processSelectedApps(selectedPendingOpps, 'pending');
			
			if(mapOppLineType.size() > 0) {
				processSelectedApps(mapOppLineType);
			}
			
			
			if(selectedPendingOpps.size() > 0 || selectedWonOpps.size() > 0)	{	
			opptyPage = new ApexPages.StandardController(oppty).view();
	     	opptyPage.setRedirect(true);
	     	system.debug('pending/won fires');
			}  
			if(selectedLostOpps.size() >0) {
				Opportunity lostOppty = [SELECT Id, Name FROM Opportunity WHERE StageName='Closed Lost' AND Name=:oppty.Name + ' - Lost'];
				if(lostOppty != null) {
					opptyPage = new PageReference('/apex/vfp_POSplit_Lost?id=' + lostOppty.id );
					system.debug('lost fires with =>' + lostOppty.Name);
					return opptyPage;
				}
	
			}
		} 
		catch (DmlException e)
		{
			ApexPages.addMessages(e);
		}
		return opptyPage;
	}
	
	
	public void processSelectedApps(Map<String, List<OpportunityLineItem>> maplist) { //public void processSelectedApps(List<OpportunityLineItem> opplist, String status) {
		//create rollback in case one of the line items fails, rollback everything
		Savepoint sp = Database.setSavepoint();		
		Opportunity oppy = [SELECT Id, Name, StageName, CurrencyIsoCode, Financial_Total__c, AccountId, isOriginal__c, MJB_Sales_Order__c, Initial_Interest__c, Customer_LPO__c, Opportunity_Description__c, Equipment__c, CloseDate,Model__c, Interstart_Delivery_Code__c,Chase_Date__c,Quotation_Date_Time__c,Customer_Reference__c FROM Opportunity WHERE id=:oppty.id];
		Opportunity wonOp = new Opportunity();
		oppy.Original_Opportunity_Total__c = oppy.Financial_Total__c;
		//get record types and assign them on creation
		List<RecordType> recordtypeList = [Select Id, DeveloperName From RecordType  where sobjecttype='Opportunity'];
		
		for(RecordType record: recordTypeList) {
			recordTypeMap.put(record.DeveloperName, record.id);
		}
		
			if(maplist.containsKey('won')) {
				//create Won Opportunity case		
			 	if(recordTypeMap.containsKey('Original_Opportunity'))
			 	wonOp.RecordTypeId = recordTypeMap.get('Won_Opportunity');					 	
			 	wonOp.AccountId = oppy.AccountId;
			 	wonOp.MJB_Sales_Order__c = oppy.MJB_Sales_Order__c;
			 	wonOp.Initial_Interest__c = oppy.Initial_Interest__c;
			 	wonOp.Opportunity_Description__c = oppy.Opportunity_Description__c;
			 	wonOp.Equipment__c = oppy.Equipment__c;
			 	wonOp.Customer_LPO__c = oppy.Customer_LPO__c;
			 	wonOp.Model__c = oppy.Model__c;
			 	wonOp.CloseDate = oppy.CloseDate;
			 	wonOp.Name = Oppty.Name;
			 	wonOp.StageName = 'Closed Won';
			 	wonOp.Interstart_Delivery_Code__c = oppy.Interstart_Delivery_Code__c;
			 	wonOp.Chase_Date__c = oppy.Chase_Date__c;
			 	wonOp.Quotation_Date_Time__c = oppy.Quotation_Date_Time__c;
			 	wonOp.Customer_Reference__c = oppy.Customer_Reference__c;
			 	wonOp.CurrencyIsoCode = oppy.CurrencyIsoCode;
			 	//wonOp.isSplit__c = True;
			 	datetime mydate = datetime.now();
			 	wonOp.Split_Date_and_Time__c = mydate.addSeconds(2);
			 	system.debug(wonOp.Split_Date_and_Time__c + ' is fired');
			 	
			 	insert wonOp; //needs to be bulked
			 	//update original
			 	oppy.Opportunity_Won__c = wonOp.id;
			 	
			 	List<OpportunityLineItem> wonList = mapList.get('won');
			 	
			 	for(OpportunityLineItem oppLineItem: wonList) {
			 		OpportunityLineItem newOppLine = new OpportunityLineItem(
			 		OpportunityId=wonOp.id, 
			 		PricebookEntryId=oppLineItem.PricebookEntryId, 
			 		Quantity=oppLineItem.Quantity, 
			 		Discount=oppLineItem.Discount, 
			 		UnitPrice=oppLineItem.UnitPrice, 
					Description=oppLineItem.Description, 
					Part_Number__c=oppLineItem.Part_Number__c, 
					VAT_Value__c=oppLineItem.VAT_Value__c, 
					VAT_Code__c=oppLineItem.VAT_Code__c, 
					VAT_Rate__c=oppLineItem.VAT_Rate__c, 
					Commission__c=oppLineItem.Commission__c, 
					Freight_Rate__c=oppLineItem.Freight_Rate__c, 
					Duty__c =oppLineItem.Duty__c, 
					Margin__c=oppLineItem.Margin__c, 
					UOM__c=oppLineItem.UOM__c, 
					Delivery_Days__c=oppLineItem.Delivery_Days__c, 
					Inquiry_Part_No__c=oppLineItem.Inquiry_Part_No__c, 
					Product_Group__c=oppLineItem.Product_Group__c, 
					Product_Group_Description__c=oppLineItem.Product_Group_Description__c, 
					Product_Group_Master__c=oppLineItem.Product_Group_Master__c, 
					Item_Number__c=oppLineItem.Item_Number__c,
					ServiceDate = oppLineItem.ServiceDate,
					NL_Code__c = oppLineItem.NL_Code__c, 
					NL_Code_Description__c = oppLineItem.NL_Code_Description__c  
			 		);
			 		
			 		OppLineItemCopyWon.add(newOppLine);
			 	}
			 	
			 	if(OppLineItemCopyWon.size() > 0) {
					system.debug('size of items copied' + OppLineItemCopyWon.size());
					try{
					 	insert OppLineItemCopyWon;
					 	system.debug('new opp item created');
					 	delete wonlist;			 	
					} catch (Exception e) {
						//rollback
						Database.rollback(sp);
					}
				 	
			 	}
			 	
			 	
			} 
			
			if(maplist.containsKey('lost')) {
				//create Lost Opportunity case
			 	Opportunity LostOp = new Opportunity();
			 	//wonOp.OwnerId = UserInfo.getUserId();
			 	if(recordTypeMap.containsKey('Lost_Opportunity'))
			 	LostOp.RecordTypeId = recordTypeMap.get('Lost_Opportunity');

			 	LostOp.AccountId = oppy.AccountId;
			 	LostOp.MJB_Sales_Order__c = oppy.MJB_Sales_Order__c;
			 	LostOp.CloseDate = oppy.CloseDate;
			 	LostOp.Initial_Interest__c = oppy.Initial_Interest__c;
			 	LostOp.Opportunity_Description__c = oppy.Opportunity_Description__c;
			 	LostOp.Equipment__c = oppy.Equipment__c;
			 	LostOp.Model__c = oppy.Model__c;		
			 	LostOp.Customer_LPO__c = oppy.Customer_LPO__c;			 		 	
			 	LostOp.Name = Oppty.Name + ' - Lost';
			 	LostOp.StageName = 'Closed Lost';
			 	LostOp.Lost_bid_review__c = 'Others';
			 	LostOp.Interstart_Delivery_Code__c = oppy.Interstart_Delivery_Code__c;
			 	LostOp.Chase_Date__c = oppy.Chase_Date__c;
			 	LostOp.Quotation_Date_Time__c = oppy.Quotation_Date_Time__c;
			 	LostOp.Customer_Reference__c = oppy.Customer_Reference__c;	
			 	LostOp.CurrencyIsoCode = oppy.CurrencyIsoCode;
			 			 	
			 	insert lostOp; //needs to be bulked
			 	//update original
			 	oppy.Opportunity_Lost__c = lostOp.id;
			 	
				
				List<OpportunityLineItem> lostList = mapList.get('lost');
				//insert the lost records
			 	for(OpportunityLineItem oppLineItem: lostList) {
			 		OpportunityLineItem lostOppLine = new OpportunityLineItem(
			 		OpportunityId=lostOp.id, 
			 		PricebookEntryId=oppLineItem.PricebookEntryId, 
			 		Quantity=oppLineItem.Quantity, 
			 		Discount=oppLineItem.Discount, 
			 		UnitPrice=oppLineItem.UnitPrice, 
					Description=oppLineItem.Description, 
					Part_Number__c=oppLineItem.Part_Number__c, 
					VAT_Value__c=oppLineItem.VAT_Value__c, 
					VAT_Code__c=oppLineItem.VAT_Code__c, 
					VAT_Rate__c=oppLineItem.VAT_Rate__c, 
					Commission__c=oppLineItem.Commission__c, 
					Freight_Rate__c=oppLineItem.Freight_Rate__c, 
					Duty__c =oppLineItem.Duty__c, 
					Margin__c=oppLineItem.Margin__c, 
					UOM__c=oppLineItem.UOM__c, 
					Delivery_Days__c=oppLineItem.Delivery_Days__c, 
					Inquiry_Part_No__c=oppLineItem.Inquiry_Part_No__c, 
					Product_Group__c=oppLineItem.Product_Group__c, 
					Product_Group_Description__c=oppLineItem.Product_Group_Description__c, 
					Product_Group_Master__c=oppLineItem.Product_Group_Master__c, 
					Item_Number__c=oppLineItem.Item_Number__c,
					line_item_status__c = 'Lost',
					ServiceDate = oppLineItem.ServiceDate,
					NL_Code__c = oppLineItem.NL_Code__c, 
					NL_Code_Description__c = oppLineItem.NL_Code_Description__c  
			 		);
			 		
			 		OppLineItemCopyLost.add(lostOppLine);
			 	}			
			 	
			 	if(OppLineItemCopyLost.size() > 0) {
			 		try{
						system.debug('size of items lost copied => ' + OppLineItemCopyLost.size());
					 	insert OppLineItemCopyLost;
					 	system.debug('lost opp item created');
				 		//delete old list
				 		delete lostlist;		
				 	} catch (Exception e) {
						//rollback
						Database.rollback(sp);
					}
				 		 	
				 	
			 	}
			 		
				
			} 
			
			if(maplist.containsKey('pending')) {
				//create Lost Opportunity case
			 	Opportunity PendingOp = new Opportunity();
			 	//wonOp.OwnerId = UserInfo.getUserId();
				if(recordTypeMap.containsKey('Pending_Split'))
			 	PendingOp.RecordTypeId = recordTypeMap.get('Pending_Split');	
			 	
			 	PendingOp.AccountId = oppy.AccountId;
			 	PendingOp.MJB_Sales_Order__c = oppy.MJB_Sales_Order__c;
			 	PendingOp.CloseDate = oppy.CloseDate;
			 	PendingOp.isPending__c = true;
			 	PendingOp.Initial_Interest__c = oppy.Initial_Interest__c;
			 	PendingOp.Opportunity_Description__c = oppy.Opportunity_Description__c;
			 	PendingOp.Equipment__c = oppy.Equipment__c;
			 	PendingOp.Model__c = oppy.Model__c;		
			 	PendingOp.Customer_LPO__c = oppy.Customer_LPO__c;			 		 	
			 	PendingOp.Name = Oppty.Name + ' - Pending';
			 	PendingOp.StageName = 'PO Awarded';
			 	PendingOp.Original_Opportunity_Name__c = Oppty.Name;
			 	PendingOp.Original_Opportunity_ID__c = wonOp.id; //won Opp id
			 	PendingOp.Opportunity_Won__c = wonOp.Id;
			 	PendingOp.Interstart_Delivery_Code__c = oppy.Interstart_Delivery_Code__c;
			 	PendingOp.Chase_Date__c = oppy.Chase_Date__c;
			 	PendingOp.Quotation_Date_Time__c = oppy.Quotation_Date_Time__c;
			 	PendingOp.Customer_Reference__c = oppy.Customer_Reference__c;	
			 	PendingOp.CurrencyIsoCode = oppy.CurrencyIsoCode;			 					 	
			 	//PendingOp.Opportunity_Lost__c = lostOp.id;
			 	insert PendingOp; //needs to be bulked
			 							
			 	//update original
			 	oppy.Opportunity_Pending__c = PendingOp.id;
				
				List<OpportunityLineItem> pendingList = mapList.get('pending');
				//insert the pending records
			 	for(OpportunityLineItem oppLineItem: pendingList) {
			 		OpportunityLineItem pendingOppLine = new OpportunityLineItem(
			 		OpportunityId=PendingOp.id, 
			 		PricebookEntryId=oppLineItem.PricebookEntryId, 
			 		Quantity=oppLineItem.Quantity, 
			 		Discount=oppLineItem.Discount, 
			 		UnitPrice=oppLineItem.UnitPrice, 
					Description=oppLineItem.Description, 
					Part_Number__c=oppLineItem.Part_Number__c, 
					VAT_Value__c=oppLineItem.VAT_Value__c, 
					VAT_Code__c=oppLineItem.VAT_Code__c, 
					VAT_Rate__c=oppLineItem.VAT_Rate__c, 
					Commission__c=oppLineItem.Commission__c, 
					Freight_Rate__c=oppLineItem.Freight_Rate__c, 
					Duty__c =oppLineItem.Duty__c, 
					Margin__c=oppLineItem.Margin__c, 
					UOM__c=oppLineItem.UOM__c, 
					Delivery_Days__c=oppLineItem.Delivery_Days__c, 
					Inquiry_Part_No__c=oppLineItem.Inquiry_Part_No__c, 
					Product_Group__c=oppLineItem.Product_Group__c, 
					Product_Group_Description__c=oppLineItem.Product_Group_Description__c, 
					Product_Group_Master__c=oppLineItem.Product_Group_Master__c, 
					Item_Number__c=oppLineItem.Item_Number__c,
					line_item_status__c = 'Pending',
					ServiceDate = oppLineItem.ServiceDate,
					NL_Code__c = oppLineItem.NL_Code__c, 
					NL_Code_Description__c = oppLineItem.NL_Code_Description__c  
			 		);
			 		
			 		OppLineItemCopyPending.add(pendingOppLine);
			 	}//end for	
			 	
			 	if(OppLineItemCopyPending.size() > 0) {
			 		try{ 		
						system.debug('size of items pending copied => ' + OppLineItemCopyPending.size());
					 	insert OppLineItemCopyPending;
					 	system.debug('pending opp item created');
				 		//delete old list
					 	delete pendinglist;
				 	} catch (Exception e) {
						//rollback
						Database.rollback(sp);
					}
				 		 	
				 		 	
				 	
			 	}
				
			} 
			
			//update the original
				if(recordTypeMap.containsKey('Original_Opportunity'))
			 	oppy.RecordTypeId = recordTypeMap.get('Original_Opportunity');				
			 	oppy.Name = oppy.Name + ' - Original';
			 	oppy.StageName = 'Partial Awarded';
			 	oppy.isOriginal__c = true;
			 	update oppy;	
			
		//} 
	}
	
}